package org.amse.ys.sndeditor.model.editor;

import org.amse.ys.sndeditor.model.*;
import org.amse.ys.sndeditor.model.drawer.AndroidDrawer;
import org.amse.ys.sndeditor.model.modules.*;
import org.amse.ys.sndeditor.model.soundfile.WavReader;
import org.amse.ys.sndeditor.ui.R.string;

import java.io.*;
import java.util.ArrayList;

public final class ImplementedEditor implements IEditor {
	public static final int NUMBER_OF_MODULES = 2; // used while reflection is
													// not implemented

	private IModule myActiveModule; // our visible module
	private IModule[] myModuleArray; // array of used initilized modules
	private static ImplementedEditor myLinkToMe; // link necessary to create
													// singleton
	final private ArrayList<ISoundFile> mySoundFile; // opened sound file

	/*
	 * Initilizing singleton
	 */
	public static ImplementedEditor initEditor(Object context) {
		if (myLinkToMe == null) {
			Localiser.init(context);
			myLinkToMe = new ImplementedEditor(context);
		}
		return myLinkToMe;
	}

	// private constructor
	private ImplementedEditor(Object context) {
		AndroidDrawer.getDrawer(context);
		myModuleArray = new IModule[NUMBER_OF_MODULES];
		myModuleArray[0] = new DebuggingModule();
		myModuleArray[1] = new SimpleDiagramModule();
		myActiveModule = myModuleArray[1];
		mySoundFile = new ArrayList<ISoundFile>();
		mySoundFile.add(new WavReader());
		for (int i = 0; i < NUMBER_OF_MODULES; i++) {
			myModuleArray[i].initilize(mySoundFile.get(0));
		}
	}

	/*
	 * Modules' methods
	 */
	public int getTimerDelay() {
		return myActiveModule.getTimerDelay();
	}

	public String getAppletName(int appletNumber) {
		return myModuleArray[appletNumber].getAppletName();
	}

	public int getNumberOfApplets() {
		return myModuleArray.length;
	}

	public void onMagnify(double timesToMagnify) {
		if (myActiveModule.isMagnifyable()) {
			myActiveModule.onMagnify(timesToMagnify);
			myActiveModule.refresh();
		} else {
			AndroidDrawer.getDrawer().showMessage(
					Localiser.getString(string.magnifying_error));
		}
	}

	public void onScroll(double x) {
		myActiveModule.onSpin(x);

	}

	public void onTimer() {
		if (myActiveModule.getTimerDelay() != -1) {
			myActiveModule.onTimer();
		} else {
			System.out
					.println("attemt to call timer for applet doesn't support timer");
		}
	}

	public void onTouch(int posX, int posY, long time) {
		myActiveModule.onTouch(posX, posY, time);
	}

	public void setActiveApplet(int numberOfApplet) {
		myActiveModule = myModuleArray[numberOfApplet];
		myActiveModule.refresh();
	}

	public void setSize(int width, int height) {
		for (int i = 0; i < myModuleArray.length; i++) {
			myModuleArray[i].setSize(width, height);
		}
		myActiveModule.refresh();

	}

	private String getOwnMenuItemName(int numberOfItem) {		
		if (numberOfItem == 0) {
			return "Close";
		} else {
			// extracting file name
			String s = mySoundFile.get(numberOfItem).getFileName();
			return s.substring(s.lastIndexOf("/") + 1);
			
			//return mySoundFile.get(numberOfItem).getFileName();
		}
		
	}

	private int getOwnNumberOfMenuOptions() {
		// the first ISoundFile is a public buffer
		return (mySoundFile.size());
	}

	private boolean onOwnMenuItemSelected(int menuItem) {		
		if (menuItem == 0) {
			ISoundFile f = myActiveModule.getSoundFile();
			for (int i = 0; i < NUMBER_OF_MODULES; i++) {
				myModuleArray[i].initilize(mySoundFile.get(0));
			}
			int index = mySoundFile.indexOf(f);
			if (index >= 0) {
				mySoundFile.get(index).closeFile();
				mySoundFile.remove(index);				
				// TODO remove all the tempoary information;
			} else {
				throw new RuntimeException("Can't find opened file");
			}
			return false;		
		} else {
			// here we should save all the opened files
			// and make acitve selected file
			try {
				reopenFile(mySoundFile.get(menuItem).getFileName());
				myActiveModule.refresh();
				AndroidDrawer.getDrawer().showMessage("Sucsess");
				
			} catch (IOException e) {
				AndroidDrawer.getDrawer().showMessage("Error reopening file");
			}
			return true;
		}
	}

	private int getOwnMenuItemIconIndex(int menuItem) {
		return -1;
		// TODO
	}

	public String getMenuItemName(int numberOfItem) {
		if (numberOfItem < myActiveModule.getNumberOfMenuOptions()) {
			return myActiveModule.getMenuItemName(numberOfItem);
		} else {
			return getOwnMenuItemName(numberOfItem
					- myActiveModule.getNumberOfMenuOptions());
		}
	}

	public int getNumberOfMenuOptions() {
		return (myActiveModule.getNumberOfMenuOptions() + getOwnNumberOfMenuOptions());
	}

	public boolean onMenuItemSelected(int menuItem) {
		if (menuItem < myActiveModule.getNumberOfMenuOptions()) {
			myActiveModule.onMenuItemSelected(menuItem);
			return true;
		} else {
			return onOwnMenuItemSelected(menuItem
					- myActiveModule.getNumberOfMenuOptions());
		}
	}

	public IDrawer getDrawer() {
		return myActiveModule.getDrawer();
	}

	public boolean isScreenChanged() {
		return myActiveModule.isScreenChanged();
	}

	public void onDPadKeyPressed() {
		myActiveModule.onDPadKeyPressed();

	}

	private void openSoundFile(String fileName) throws IOException {
		ISoundFile f = new WavReader();
		f.openFromFile(fileName);
		mySoundFile.add(f);
		for (int i = 0; i < NUMBER_OF_MODULES; i++) {
			myModuleArray[i].initilize(f);
		}
	}

	public void onOpenFile(final String fileName) throws IOException {
		// save all information
		for (int i = 0; i < mySoundFile.size(); i++) {
			ISoundFile f = mySoundFile.get(i);
			if (f.isOpened() && (!f.stateIsSaved())) {
				f.saveTempoaryInformation();
			}
		}
		openSoundFile(fileName);
	}

	public int getMenuItemIconIndex(int numberOfItem) {
		if (numberOfItem < myActiveModule.getNumberOfMenuOptions()) {
			return myActiveModule.getMenuItemIconIndex(numberOfItem);
		} else {
			return getOwnMenuItemIconIndex(numberOfItem
					- myActiveModule.getNumberOfMenuOptions());
		}

		/*
		 * if (numberOfItem >= getOwnNumberOfMenuOptions()) { return
		 * myActiveModule.getMenuItemIconIndex(numberOfItem -
		 * getOwnNumberOfMenuOptions()); } else { return
		 * getOwnMenuItemIconIndex(numberOfItem); }
		 */
	}

	public static IEditor getEditor() {
		return myLinkToMe;
	}

	@Override
	public boolean fileIsOpened(String fileName) {
		for (int i = 0; i < mySoundFile.size(); i++) {
			final ISoundFile f = mySoundFile.get(i);
			if (f.isOpened()) {
				if (f.getFileName().equals(fileName)) /*
													 * ||(WavReader.
													 * HasTempoaryInformation
													 * (fileName)))
													 */{
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public void reopenFile(String fileName) throws IOException {
		// save all information
		for (int i = 0; i < mySoundFile.size(); i++) {
			ISoundFile f = mySoundFile.get(i);
			if (f.isOpened() && (!f.stateIsSaved())) {
				f.saveTempoaryInformation();
			}
		}
		for (int i = 0; i < mySoundFile.size(); i++) {
			final ISoundFile f = mySoundFile.get(i);
			if (f.isOpened()) {
				if (f.getFileName().equals(fileName)) {
					f.openTempoaryInformation();
					for (int j = 0; j < NUMBER_OF_MODULES; j++) {
						myModuleArray[j].initilize(f);
					}
				}
			}
		}
	}

}
